﻿using System;

public class GlobalMembersGame_object: GlobalMembersGame_control//
{
	public new delegate  void  funcDelegate(LCUI_Widget_ UnnamedParameter1);

	//*
	// * 创建一个动作集
	// * 创建的动作集将记录至动作库中
	// * @returns
	// *	正常则返回指向动作库中的该动作集的指针，失败则返回NULL
	// 

	//*
	// * 创建一个动作集
	// * 创建的动作集将记录至动作库中
	// * @returns
	// *	正常则返回指向动作库中的该动作集的指针，失败则返回NULL
	// 
	public static ActionData_ Action_Create()
	{
		ActionData_ p;
		ActionData_ action = new ActionData_();

		Queue_Init(action.frame, typeof(ActionFrameData_), null);
		action.replay = DefineConstantsGame_object.TRUE;

		if (action_database_inited == null)
		{
			Queue_Init(action_database, typeof(ActionData_), ActionData_Destroy);
			action_database_inited = DefineConstantsGame_object.TRUE;
		}
		Queue_Lock(action_database);
		// 记录该动画至库中
		p = (ActionData_)Queue_Add(action_database, action);
		Queue_Unlock(action_database);
		return p;
	}


    //* 设置动作是否重复播放 

    //* 设置动作是否重复播放 
    public static void Action_SetReplay(ActionData_ action, LCUI_BOOL replay)
	{
		action.replay = replay;
	}

//*
// * 删除一个动画
// * 从动画库中删除指定的动画
// * @param action
// *	需删除的动画
// * @returns
// *	正常则返回0，失败则返回-1
// 

	//*
	// * 删除一个动画
	// * 从动画库中删除指定的动画
	// * @param action
	// *	需删除的动画
	// * @returns
	// *	正常则返回0，失败则返回-1
	// 
	public static int Action_Delete(ActionData_ action)
	{
		int n;
		ActionData_ tmp;

		Queue_Lock(action_database);
		//n = Queue_GetTotal(action_database);
		for(n=Queue_GetTotal(action_database); n>=0; --n)
		{
			tmp = (ActionData_)Queue_Get(action_database, n);
			if(tmp == action)
			{
				Queue_Delete(action_database, n);
				break;
			}
		}
		Queue_Unlock(action_database);
		if(n < 0)
		{
			return -1;
		}
		return 0;
	}


	public static int GameObject_AtActionDone(LCUI_Widget_ widget, int action_id, funcDelegate func)
	{
		GameObject_ obj;
		ActionRec_ p_rec;

		obj = (GameObject_)Widget_GetPrivData(widget);
		p_rec = GameObject_FindActionRec(obj, action_id);
		if(p_rec == null)
		{
			return -1;
		}
		p_rec.done = func;
		return 0;
	}

	public static int GameObject_AtActionUpdate(LCUI_Widget_ widget, int action_id, funcDelegate func)
	{
		GameObject_ obj;
		ActionRec_ p_rec;

		obj = (GameObject_)Widget_GetPrivData(widget);
		p_rec = GameObject_FindActionRec(obj, action_id);
		if(p_rec == null)
		{
			return -1;
		}
		p_rec.update = func;
		return 0;
	}

//* 获取当前动作帧的序号 

	//* 获取当前动作帧的序号 
	public static int GameObject_GetCurrentActionFrameNumber(LCUI_Widget_ widget)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.n_frame;
	}

//* 获取指定动作帧的顶点相对于底线的距离 

	//* 获取指定动作帧的顶点相对于底线的距离 
	public static int GameObject_GetFrameTop(LCUI_Widget_ widget, int action_id, int n_frame)
	{
		int tmp;
		GameObject_ obj;
		ActionFrameData_ frame;
		ActionRec_ p_rec;

		obj = (GameObject_)Widget_GetPrivData(widget);
		p_rec = GameObject_FindActionRec(obj, action_id);
		if (p_rec == null)
		{
			return 0;
		}
		tmp = Queue_GetTotal(p_rec.action.frame);
		if(n_frame >= tmp)
		{
			n_frame = tmp-1;
		}
		frame = (ActionFrameData_)Queue_Get(p_rec.action.frame, n_frame);
		if(frame == null)
		{
			return 0;
		}
		return frame.graph.h + frame.offset.y;
	}

//* 获取当前帧的顶点相对于底线的距离 

	//* 获取当前帧的顶点相对于底线的距离 
	public static int GameObject_GetCurrentFrameTop(LCUI_Widget_ widget)
	{
		int n_frame;
		GameObject_ obj;
		ActionFrameData_ frame;

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.current == null)
		{
			obj.current = (ActionRec_)Queue_Get(obj.action_list, 0);
			if(obj.current == null)
			{
				return 0;
			}
		}
		n_frame = obj.n_frame;
		if(n_frame == Queue_GetTotal(obj.current.action.frame))
		{
			n_frame -= 1;
		}
		frame = (ActionFrameData_)Queue_Get(obj.current.action.frame, n_frame);
		if(frame == null)
		{
			return 0;
		}
		return frame.graph.h + frame.offset.y;
	}

	public static void GameObject_AtXSpeedToZero(LCUI_Widget_ widget, double acc, funcDelegate func)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		GameObject_SetXAcc(widget, acc);
		obj.at_xspeed_to_zero = func;

	}

	//* 在Z轴移动速度为0时进行响应  
	public static void GameObject_AtZeroZSpeed(LCUI_Widget_ widget, funcDelegate func)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.at_zero_zspeed = func;
	}

	//* 设置在对象着地时进行响应 
	public static void GameObject_AtLanding(LCUI_Widget_ widget, double z_speed, double z_acc, funcDelegate func)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj.z_speed = z_speed;
		obj.space_obj.z_acc = z_acc;
		obj.at_landing = func;
	}

	//* 设定当速度达到一定值时进行响应（在有加速度的情况下） 
	public static void GameObject_AtZSpeed(LCUI_Widget_ widget, double target_z_speed, funcDelegate func)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.at_zspeed = func;
		obj.target_z_speed = target_z_speed;
	}

	//* 设置在被攻击时进行响应 
	public static void GameObject_AtUnderAttack(LCUI_Widget_ widget, funcDelegate func)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.at_under_attack = func;
	}


	//* 在游戏对象移动时进行响应 
	public static void GameObject_AtMove(LCUI_Widget_ widget, funcDelegate func)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.at_move = func;
	}

//* 设置在被其它对象触碰到时进行响应 
public delegate void funcDelegate2(LCUI_Widget_ UnnamedParameter1, LCUI_Widget_ UnnamedParameter2);

	//* 设置在被其它对象触碰到时进行响应 
	public static void GameObject_AtTouch(LCUI_Widget_ widget, funcDelegate2 func)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.at_touch = func;
	}

//* 获取攻击者信息 

	//* 获取攻击者信息 
	public static LCUI_Queue GameObject_GetAttackerInfo(LCUI_Widget_ widget)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.attacker_info;
	}

//* 获取对象的受攻击范围 

	//* 获取对象的受攻击范围 
	public static int GameObject_GetHitRange(LCUI_Widget_ widget,out RangeBox_ range)
	{
		int n_frame;
		GameObject_ obj;
		ActionFrameData_ frame;
		range = default(RangeBox_);
		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj == null || obj.current == null)
		{
			return -1;
		}
		n_frame = obj.n_frame;
		if(obj.n_frame == Queue_GetTotal(obj.current.action.frame))
		{
			n_frame -= 1;
		}
		frame = (ActionFrameData_)Queue_Get(obj.current.action.frame, n_frame);
		if(frame == null)
		{
			return -2;
		}
		if(frame.hitbox.x_width <= 0 || frame.hitbox.y_width <= 0 || frame.hitbox.z_width <= 0)
		{
			 return -3;
		}
		// 动作图是否水平翻转，只影响范围框的X轴坐标
		if(obj.horiz_flip)
		{
			range.x = (int)obj.space_obj.x - frame.hitbox.x;
			range.x -= frame.hitbox.x_width;
		}
		else
		{
			range.x = (int)obj.space_obj.x + frame.hitbox.x;
		}
		range.x_width = frame.hitbox.x_width;
		range.y = (int)obj.space_obj.y + frame.hitbox.y;
		range.y_width = frame.hitbox.y_width;
		range.z = (int)obj.space_obj.z + frame.hitbox.z;
		range.z_width = frame.hitbox.z_width;
		return 0;
	}

//* 获取对象的攻击范围 

	//* 获取对象的攻击范围 
	public static int GameObject_GetAttackRange(LCUI_Widget_ widget,out RangeBox_ range)
	{
		int n_frame;
		GameObject_ obj;
		ActionFrameData_ frame;
		range = default(RangeBox_);
		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj == null || obj.current == null)
		{
			return -1;
		}
		n_frame = obj.n_frame;
		if(obj.n_frame == Queue_GetTotal(obj.current.action.frame))
		{
			n_frame -= 1;
		}
		frame = (ActionFrameData_)Queue_Get(obj.current.action.frame, n_frame);
		if(frame == null)
		{
			return -2;
		}
		if(frame.atkbox.x_width <= 0 || frame.atkbox.y_width <= 0 || frame.atkbox.z_width <= 0)
		{
			 return -3;
		}
		// 动作图是否水平翻转，只影响范围框的X轴坐标
		if(obj.horiz_flip)
		{
			range.x = (int)obj.space_obj.x - frame.atkbox.x;
			range.x -= frame.atkbox.x_width;
		}
		else
		{
			range.x = (int)obj.space_obj.x + frame.atkbox.x;
		}
		range.x_width = frame.atkbox.x_width;
		range.y = (int)obj.space_obj.y + frame.atkbox.y;
		range.y_width = frame.atkbox.y_width;
		range.z = (int)obj.space_obj.z + frame.atkbox.z;
		range.z_width = frame.atkbox.z_width;
		return 0;
	}

//* 判断两个范围是否相交 

	//* 判断两个范围是否相交 
	public static LCUI_BOOL RangeBox_IsIntersect(RangeBox_ range1, RangeBox_ range2)
	{
		// 先判断在X轴上是否有相交
		if(range1.x + range1.x_width-1 <= range2.x)
		{
			return DefineConstantsGame_object.FALSE;
		}
		if(range2.x + range2.x_width-1 <= range1.x)
		{
			return DefineConstantsGame_object.FALSE;
		}
		// 然后判断在X轴上是否有相交
		if(range1.y + range1.y_width-1 <= range2.y)
		{
			return DefineConstantsGame_object.FALSE;
		}
		if(range2.y + range2.y_width-1 <= range1.y)
		{
			return DefineConstantsGame_object.FALSE;
		}
		// 最后判断在Z轴上是否有相交
		if(range1.z + range1.z_width-1 <= range2.z)
		{
			return DefineConstantsGame_object.FALSE;
		}
		if(range2.z + range2.z_width-1 <= range1.z)
		{
			return DefineConstantsGame_object.FALSE;
		}
		return DefineConstantsGame_object.TRUE;
	}

//* 检测指定游戏对象是否已经成为另一游戏对象的受攻击者 

	//* 检测指定游戏对象是否已经成为另一游戏对象的受攻击者 
	public static  LCUI_BOOL GameObject_HaveVictim(LCUI_Widget_ attacker, LCUI_Widget_ victim)
	{
		int i;
		int n;
		LCUI_Widget_ tmp;
		GameObject_ atk_obj;

		atk_obj = (GameObject_)Widget_GetPrivData(attacker);
		n = Queue_GetTotal(atk_obj.victim);
		// 在攻击者的受害者记录中查找
		for(i =0; i<n; ++i)
		{
			tmp = (LCUI_Widget_)Queue_Get(atk_obj.victim, i);
			// 若当前受害者已经在记录中
			if(tmp == victim)
			{
				return DefineConstantsGame_object.TRUE;
			}
		}
		return DefineConstantsGame_object.FALSE;
	}

//* 直接为攻击者添加受害者记录 

	//* 直接为攻击者添加受害者记录 
	public static int GameObject_DirectAddVictim(LCUI_Widget_ attacker, LCUI_Widget_ victim)
	{
		AttackerInfo_ info = new AttackerInfo_();
		GameObject_ atk_obj;
		GameObject_ hit_obj;

		atk_obj = (GameObject_)Widget_GetPrivData(attacker);
		hit_obj = (GameObject_)Widget_GetPrivData(victim);
		// 准备攻击者的相关信息
		info.attacker = attacker;
		info.attacker_action = GameObject_GetCurrentActionID(attacker);
		// 为攻击者添加受害者记录
		Queue_AddPointer(atk_obj.victim, victim);
		// 为受害者记录攻击者的信息
		//if(Queue_Add(hit_obj.attacker_info, info)< 0)
		if (Queue_Add(hit_obj.attacker_info, info)==null)
		{
			return -1;
		}
		// 若设置了攻击响应
		if(hit_obj.at_under_attack!=null)
		{
			hit_obj.at_under_attack(victim);
		}
		return 0;
	}

//* 为攻击者添加受害者记录，若已存在，则不添加 

	//* 为攻击者添加受害者记录，若已存在，则不添加 
	public static int GameObject_AddVictim(LCUI_Widget_ attacker, LCUI_Widget_ victim)
	{
		// 如果已经成为了受害者，则退出
		if (GameObject_HaveVictim(attacker, victim))
		{
			return -1;
		}
		return GameObject_DirectAddVictim(attacker, victim);
	}

//* 创建游戏对象库 

	//* 创建游戏对象库 
	public static int GameObjectLibrary_Create(ref LCUI_Queue library)
	{
		Queue_Init(library, typeof(LCUI_Widget_), null);
		Queue_UsingPointer(library);
		return 0;
	}

//* 销毁游戏对象库 

	//* 销毁游戏对象库 
	public static int GameObjectLibrary_Destroy(ref LCUI_Queue library)
	{
		int i;
		int n;
		LCUI_Widget_ @object;

		Queue_Lock(library);
		n = Queue_GetTotal(library);
		for(i =0; i<n; ++i)
		{
			@object = (LCUI_Widget_)Queue_Get(library, i);
			if (@object != null)
			{
				Widget_Destroy(@object);
			}
		}
		Queue_Unlock(library);
		return 0;
	}

	public static void GameObjectLibrary_DispatchEvent(ref LCUI_Queue library)
	{
		int i;
		int n;
		double z_acc;
		GameObject_ obj;
		LCUI_Widget_ widget;

		n = Queue_GetTotal(library);
		for(i =0; i<n; ++i)
		{
			widget = (LCUI_Widget_)Queue_Get(library, i);
			obj = (GameObject_)Widget_GetPrivData(widget);
			if(obj == null || obj.state != DefineConstantsGame_object.ACTION_STATE_PLAY)
			{
				continue;
			}
			GameObject_ProcAttack(widget);
			GameObject_ProcTouch(widget);
			// 若在X轴的移动速度接近0
			if((obj.space_obj.x_acc > 0 && obj.space_obj.x_speed >= 0) || (obj.space_obj.x_acc < 0 && obj.space_obj.x_speed <= 0))
			{
				obj.space_obj.x_acc = 0;
				obj.space_obj.x_speed = 0;
				Widget_Update(widget);
				if(obj.at_xspeed_to_zero!=null)
				{
					obj.at_xspeed_to_zero(widget);
				}
			}
			z_acc = obj.space_obj.z_acc/DefineConstantsGame_object.FRAMES_PER_SEC;
			if(obj.at_zspeed!=null)
			{
				if(obj.space_obj.z_acc > 0)
				{
					if(obj.space_obj.z_speed >= obj.target_z_speed && obj.space_obj.z_speed - z_acc < obj.target_z_speed)
					{
						obj.at_zspeed(widget);
					}
				}
				else if(obj.space_obj.z_acc < 0)
				{
					if(obj.space_obj.z_speed >= obj.target_z_speed && obj.space_obj.z_speed + z_acc <= obj.target_z_speed)
					{
						obj.at_zspeed(widget);
					}
				}
			}
			// 若在Z轴的移动速度接近0
			if((obj.space_obj.z_acc > 0 && obj.space_obj.z_speed >= -z_acc && obj.space_obj.z_speed < z_acc) || (obj.space_obj.z_acc < 0 && obj.space_obj.z_speed >= z_acc && obj.space_obj.z_speed < -z_acc))
			{
				Widget_Update(widget);
				if(obj.at_zero_zspeed!=null)
				{
					obj.at_zero_zspeed(widget);
				}
			}
	//        *
	//		目前假设地面的Z坐标为0，当对象的Z坐标达到0时就认定它着陆了。
	//		暂不考虑其他对象对当前对象的着陆点的影响。
	//		*
			if((obj.space_obj.z_acc > 0 && obj.space_obj.z > 0) || (obj.space_obj.z_acc < 0 && obj.space_obj.z < 0) || (obj.space_obj.z <= 0 && obj.space_obj.z_speed < 0 && obj.space_obj.z_acc == 0))
			{
				obj.space_obj.z = 0;
				obj.space_obj.z_acc = 0;
				obj.space_obj.z_speed = 0;
				Widget_Update(widget);
				if(obj.at_landing!=null)
				{
					obj.at_landing(widget);
				}
			}
			if(obj.at_move!=null)
			{
				obj.at_move(widget);
			}
		}
	}

	public static void GameObjectLibrary_UpdateAction(ref LCUI_Queue library)
	{
		int i;
		int n;
		int total;
		int lost_ms;
		int frame_ms;
		LCUI_BOOL need_draw = DefineConstantsGame_object.FALSE;
		LCUI_Widget_ widget;
//C++ TO C# CONVERTER TODO TASK: Pointer arithmetic is detected on this variable, so pointers on this variable are left unchanged.
		GameObject_  obj ;
		//ActionFrameData_ frame = null;
		
		Queue_Lock(library);
		total = Queue_GetTotal(library);
		for(i =0; i<total; ++i)
		{
			
			widget = (LCUI_Widget_)Queue_Get(library, i);
			obj = (GameObject_)Widget_GetPrivData(widget);
			// 忽略无效或者未处于播放状态的对象
			if(obj == null || obj.state != DefineConstantsGame_object.ACTION_STATE_PLAY)
			{
				continue;
			}
			// 忽略没有动作动画的对象
			if(obj.current == null)
			{
				continue;
			}
			n = Queue_GetTotal(obj.current.action.frame);
			// 忽略 已经到最后一帧 且 无需重新播放动作 的对象
			if(obj.n_frame == n && !obj.current.action.replay)
			{
				continue;
			}
			// 获取流逝的时间
			lost_ms = (int)LCUI_GetTicks(obj.action_start_time);
			//print("obj.n_frame:  " + obj.n_frame);
			// 获取该帧的总停留时间
			frame_ms = Action_GetFrameSleepTime(obj.current.action, obj.n_frame);

			
			// 若已经超出总停留时间
			if (lost_ms >= frame_ms)
			{
				++obj.n_frame;
				obj.action_start_time = LCUI_GetTickCount();
				GameObjectLibrary_UpdateObjectPos(widget);
				// 标记这个对象需要重绘
				need_draw = DefineConstantsGame_object.TRUE;
			}
			else
			{
				continue;
			}
			// 若当前帧号超出总帧数
			if(obj.n_frame >= n)
			{
				//* 若该动作需要重复播放
				if(obj.current.action.replay)
				{
					obj.n_frame = 0;
					obj.action_start_time = LCUI_GetTickCount();
				}
				else
				{
					obj.n_frame = n;
				}
				if(obj.current.done!=null)
				{
					obj.current.done(widget);
				}
			}
			if (need_draw )
			{
				if (Action_IsNewAttack(obj.current.action, obj.n_frame) )
				{
					GameObject_ClearAttack(widget);
				}
				if(obj.current.update!=null)
				{
					obj.current.update(widget);
				}
				Widget_Draw(widget,obj .current , obj.n_frame);
			}
		}
		Queue_Unlock(library);
	}

//*
// * 切换对象的动作
// * @param widget
// *	目标ActiveBox部件
// * @param action_id
// *	切换至的动画的标识号
// * @return
// *	切换成功则返回0，未找到指定ID的动画记录，则返回-1
// 


	//*
	// * 切换对象的动作
	// * @param widget
	// *	目标ActiveBox部件
	// * @param action_id
	// *	切换至的动画的标识号
	// * @return
	// *	切换成功则返回0，未找到指定ID的动画记录，则返回-1
	// 
	public static int GameObject_SwitchAction(LCUI_Widget_ widget, int action_id)
	{
		ActionRec_ p_rec;
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		p_rec = GameObject_FindActionRec(obj, action_id);
		if(p_rec == null)
		{
			return -1;
		}
		Queue_Lock(obj.library);
		obj.current = p_rec;
		obj.n_frame = 0;
		obj.action_start_time = LCUI_GetTickCount();
		obj.action_total_ms = Action_GetFrameSleepTime(p_rec.action, 0);
		obj.action_pause_ms = 0;
		if(obj.state == DefineConstantsGame_object.ACTION_STATE_PAUSE)
		{
			obj.action_pause_time = LCUI_GetTickCount();
		}
		GameObjectLibrary_UpdateObjectPos(widget);
		if (Action_IsNewAttack(obj.current.action, obj.n_frame) )
		{
			GameObject_ClearAttack(widget);
		}
		Queue_Unlock(obj.library);
		// 标记数据为无效，以根据当前动作动画来更新数据
		obj.data_valid = DefineConstantsGame_object.FALSE;
		Widget_Draw(widget);
		return 0;
	}

//* 获取当前动作动画的ID 

	//* 获取当前动作动画的ID 
	public static int GameObject_GetCurrentActionID(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.current == null)
		{
			obj.current = (ActionRec_)Queue_Get(obj.action_list, 0);
			if(obj.current == null)
			{
				return -1;
			}
		}
		return obj.current.id;
	}

	public static int GameObject_ResetAction(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.current == null)
		{
			obj.current = (ActionRec_)Queue_Get(obj.action_list, 0);
			if(obj.current == null)
			{
				return -1;
			}
		}
		obj.n_frame = 0;
		obj.action_total_ms = Action_GetFrameSleepTime(obj.current.action, 0);
		obj.action_start_time = LCUI_GetTickCount();
		obj.action_pause_ms = 0;
		Widget_Draw(widget);
		return 0;
	}

//* 播放对象的动作 

	//* 播放对象的动作 
	public static int GameObject_PlayAction(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.current == null)
		{
			obj.current = (ActionRec_)Queue_Get(obj.action_list, 0);
			if(obj.current == null)
			{
				return -1;
			}
		}
		Queue_Lock(obj.library);
		if(obj.state != DefineConstantsGame_object.ACTION_STATE_PLAY)
		{
			obj.state = DefineConstantsGame_object.ACTION_STATE_PLAY;
			obj.action_pause_ms = (int)LCUI_GetTicks(obj.action_pause_time);
		}
		obj.n_frame = 0;
		obj.action_start_time = LCUI_GetTickCount();
		obj.action_total_ms = Action_GetFrameSleepTime(obj.current.action, 0);
		GameObjectLibrary_UpdateObjectPos(widget);
		Queue_Unlock(obj.library);
		Widget_Draw(widget);
		if(obj.current.update!=null)
		{
			obj.current.update(widget);
		}
		return 0;
	}

//* 暂停对象的动作 

	//* 暂停对象的动作 
	public static int GameObject_PauseAction(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.current == null)
		{
			return -1;
		}
		Queue_Lock(obj.library);
		if(obj.state == DefineConstantsGame_object.ACTION_STATE_PLAY)
		{
			obj.action_pause_time = LCUI_GetTickCount();
			obj.action_pause_ms = 0;
			obj.state = DefineConstantsGame_object.ACTION_STATE_PAUSE;
			GameObjectLibrary_UpdateObjectPos(widget);
		}
		Queue_Unlock(obj.library);
		return 0;
	}

//*
// * 为动作添加一帧动作图
// * @param action
// *	目标动作
// * @param offset_x
// *	人物底线中点相对于动作图低边中点的X轴的偏移量
// * @param offset_y
// *	人物底线中点相对于动作图低边中点的Y轴的偏移量
// * @param graph
// *	动作图
// * @param sleep_time
// *	动作图的停留时间，单位时间为20毫秒，即当它的值为50时，该帧动作图停留1秒
// * @return
// *	正常则返回该帧动作图的序号，失败返回-1
// 

	//*
	// * 为动作添加一帧动作图
	// * @param action
	// *	目标动作
	// * @param offset_x
	// *	人物底线中点相对于动作图低边中点的X轴的偏移量
	// * @param offset_y
	// *	人物底线中点相对于动作图低边中点的Y轴的偏移量
	// * @param graph
	// *	动作图
	// * @param sleep_time
	// *	动作图的停留时间，单位时间为20毫秒，即当它的值为50时，该帧动作图停留1秒
	// * @return
	// *	正常则返回该帧动作图的序号，失败返回-1
	// 
	public static int Action_AddFrame(ActionData_ action, int offset_x, int offset_y, LCUI_Graph_ graph, int sleep_time)
	{
		ActionFrameData_ frame = new ActionFrameData_();

		frame.sleep_time = sleep_time *DefineConstantsGame_object.REFRESH_INTERVAL_TIME;
		frame.offset.x = offset_x;
		frame.offset.y = offset_y;
		frame.graph = graph;
		frame.atkbox.x = frame.hitbox.x = 0;
		frame.atkbox.y = frame.hitbox.y = 0;
		frame.atkbox.z = frame.hitbox.z = 0;
		frame.atkbox.x_width = frame.hitbox.x_width = 0;
		frame.atkbox.y_width = frame.hitbox.y_width = 0;
		frame.atkbox.z_width = frame.hitbox.z_width = 0;
		frame.new_attack = DefineConstantsGame_object.FALSE;
		if(Queue_Add(action.frame, frame)!=null)
		{
			return 0;
		}
		return -1;
	}

	public static int Action_SetNewAttack(ActionData_ action, int n_frame, LCUI_BOOL flag)
	{
		ActionFrameData_ p_frame;
		if(n_frame < 0)
		{
			return -1;
		}
		p_frame = (ActionFrameData_)Queue_Get(action.frame, n_frame);
		p_frame.new_attack = flag;
		return 0;
	}

	public static int Action_SetAttackRange(ActionData_ action, int n_frame, RangeBox_ attack_range)
	{
		ActionFrameData_ p_frame;
		if(n_frame < 0)
		{
			return -1;
		}
		p_frame = (ActionFrameData_)Queue_Get(action.frame, n_frame);
//C++ TO C# CONVERTER WARNING: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created if it does not yet exist:
//ORIGINAL LINE: p_frame->atkbox = attack_range;
		p_frame.atkbox.CopyFrom(attack_range);
		return 0;
	}

	public static int Action_SetHitRange(ActionData_ action, int n_frame, RangeBox_ hit_range)
	{
		ActionFrameData_ p_frame;
		if(n_frame < 0)
		{
			return -1;
		}
		p_frame = (ActionFrameData_)Queue_Get(action.frame, n_frame);
//C++ TO C# CONVERTER WARNING: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created if it does not yet exist:
//ORIGINAL LINE: p_frame->hitbox = hit_range;
		p_frame.hitbox.CopyFrom(hit_range);
		return 0;
	}

//* 为对象添加一个动作 

	//* 为对象添加一个动作 
	public static int GameObject_AddAction(LCUI_Widget_ widget, ActionData_ action, int id)
	{
		int i;
		int n;
		ActionRec_ rec = new ActionRec_();
		ActionRec_ p_rec;
		GameObject_ obj;

		if (action == null)
		{
			return -1;
		}
		obj = (GameObject_)Widget_GetPrivData(widget);
		Queue_Lock(obj.action_list);
		n = Queue_GetTotal(obj.action_list);
		// 先寻找是否有相同ID的动作动画
		for(i =0; i<n; ++i)
		{
			p_rec = (ActionRec_)Queue_Get(obj.action_list, i);
			if (p_rec == null)
			{
				continue;
			}
			// 有则覆盖
			if(p_rec.id == id)
			{
				p_rec.action = action;
				break;
			}
		}
		if(i < n)
		{
			Queue_Unlock(obj.action_list);
			return 0;
		}
		rec.action = action;
		rec.id = id;
		rec.done = null;
		rec.update = null;
		// 添加至动作列表中
		if(Queue_Add(obj.action_list, rec)!=null)
		{
			Queue_Unlock(obj.action_list);
			return 0;
		}
		Queue_Unlock(obj.action_list);
		return -2;
	}

//* 设置对象是否进行水平翻转 

	//* 设置对象是否进行水平翻转 
	public static void GameObject_SetHorizFlip(LCUI_Widget_ widget, LCUI_BOOL flag)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.horiz_flip != flag)
		{
			obj.horiz_flip = flag;
			obj.data_valid = DefineConstantsGame_object.FALSE;
			Widget_Draw(widget);
		}
	}

//* 设置相对于X轴的加速度 

	//* 设置相对于X轴的加速度 
	public static void GameObject_SetXAcc(LCUI_Widget_ widget, double acc)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj.x_acc = acc;
	}

//* 获取相对于X轴的加速度 

	//* 获取相对于X轴的加速度 
	public static  double GameObject_GetXAcc(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.space_obj.x_acc;
	}

//* 设置在Y轴的坐标 

	//* 设置在Y轴的坐标 
	public static void GameObject_SetY(LCUI_Widget_ widget, double y)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj.y = y;
	}

//* 获取在Y轴的坐标 

	//* 获取在Y轴的坐标 
	public static  double GameObject_GetY(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.space_obj.y;
	}

//* 设置相对于Y轴的加速度 

	//* 设置相对于Y轴的加速度 
	public static void GameObject_SetYAcc(LCUI_Widget_ widget, double acc)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj.y_acc = acc;
	}

//* 获取相对于Y轴的加速度 

	//* 获取相对于Y轴的加速度 
	public static  double GameObject_GetYAcc(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.space_obj.y_acc;
	}

//* 设置相对于Y轴的加速度 

	//* 设置相对于Y轴的加速度 
	public static void GameObject_SetZAcc(LCUI_Widget_ widget, double acc)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj.z_acc = acc;
	}

//* 获取相对于Z轴的加速度 

	//* 获取相对于Z轴的加速度 
	public static  double GameObject_GetZAcc(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.space_obj.z_acc;
	}

//* 设置游戏对象在X轴的移动速度 

	//* 设置游戏对象在X轴的移动速度 
	public static void GameObject_SetXSpeed(LCUI_Widget_ widget, double x_speed)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj.x_speed = x_speed;
		Widget_Update(widget, obj);
	}

//* 获取游戏对象在X轴的移动速度 

	//* 获取游戏对象在X轴的移动速度 
	public static  double GameObject_GetXSpeed(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.space_obj.x_speed;
	}

//* 设置游戏对象在Y轴的移动速度 

	//* 设置游戏对象在Y轴的移动速度 
	public static void GameObject_SetYSpeed(LCUI_Widget_ widget, double y_speed)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj.y_speed = y_speed;
		Widget_Update(widget, obj);
	}

//* 获取游戏对象在Y轴的移动速度 

	//* 获取游戏对象在Y轴的移动速度 
	public static  double GameObject_GetYSpeed(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.space_obj.y_speed;
	}

//* 获取游戏对象在Z轴的坐标 

	//* 获取游戏对象在Z轴的坐标 
	public static  double GameObject_GetZ(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.space_obj.z;
	}

//* 设置游戏对象在Z轴的移动速度 

	//* 设置游戏对象在Z轴的移动速度 
	public static void GameObject_SetZSpeed(LCUI_Widget_ widget, double z_speed)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj.z_speed = z_speed;
		Widget_Update(widget,obj);
	}

//* 获取游戏对象在Z轴的移动速度 

	//* 获取游戏对象在Z轴的移动速度 
	public static double GameObject_GetZSpeed(LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.space_obj.z_speed;
	}

//* 设置游戏对象在Z轴的坐标 

	//* 设置游戏对象在Z轴的坐标 
	public static void GameObject_SetZ(LCUI_Widget_ widget, double z)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj.z = z;
	}

//* 将游戏对象添加至容器中 

	//* 将游戏对象添加至容器中 
	public static void GameObject_AddToContainer(LCUI_Widget_ widget, LCUI_Widget_ ctnr)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		Widget_Container_Add(ctnr, widget);
		Widget_Container_Add(ctnr, obj.shadow);
	}

//* 获取游戏对象脚底中心坐标（相对于部件容器） 

	//* 获取游戏对象脚底中心坐标（相对于部件容器） 
	public static int GameObject_GetFootPos(LCUI_Widget_ widget, LCUI_Pos_ pos)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_GetPrivData(widget);
		pos.x = obj.x;
		pos.y = obj.y;
		return 0;
	}

//* 设置游戏对象的X轴坐标 

	//* 设置游戏对象的X轴坐标 
	public static void GameObject_SetX(LCUI_Widget_ widget, double x)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj.x = x;
	}

//* 获取游戏对象的X轴坐标 

	//* 获取游戏对象的X轴坐标 
	public static double GameObject_GetX(LCUI_Widget_ widget)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		return obj.space_obj.x;
	}

//* 设置填充颜色 

	//* 设置填充颜色 
	public static void GameObject_SetFillColor(LCUI_Widget_ widget, LCUI_BOOL flag, LCUI_RGB_ color)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
//C++ TO C# CONVERTER WARNING: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created if it does not yet exist:
//ORIGINAL LINE: obj->fill_color = color;
		obj.fill_color.CopyFrom(color);
		obj.need_fill_color = flag;
	}

//* 设置游戏对象的阴影图像 

	//* 设置游戏对象的阴影图像 
	public static void GameObject_SetShadow(LCUI_Widget_ widget, LCUI_Graph_ img_shadow)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		Widget_Resize(obj.shadow, Graph_GetSize(img_shadow));
		Widget_SetBackgroundImage(obj.shadow, img_shadow);
	}

//* 设置游戏对象的阴影是否可见 

	//* 设置游戏对象的阴影是否可见 
	public static void GameObject_SetShadowVisible(LCUI_Widget_ widget, LCUI_BOOL visible)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.shadow_visible = visible;
		if (visible )
		{
			Widget_Show(obj.shadow);
		}
		else
		{
			Widget_Hide(obj.shadow);
		}
	}

//* 清空攻击记录 

	//* 清空攻击记录 
	public static void GameObject_ClearAttack(LCUI_Widget_ widget)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		while(Queue_Delete(obj.victim, 0));
	}

	////* 获取指定范围内的游戏对象 
	//public  LCUI_Widget_* GameObject_GetObjectInRange( LCUI_Widget_ widget, RangeBox_ range, LCUI_BOOL specific_action, int action_id);

	////* 获取攻击范围内的游戏对象 
	//public  LCUI_Widget_* GameObject_GetObjectInAttackRange( LCUI_Widget_ widget, int attack_action_id, LCUI_BOOL specific_action, int action_id);

	//public  LCUI_Widget_* GameObject_New(GameSpaceData_ *space, ref LCUI_Queue *library);

	//public void GameObject_Register();

	//#endif



	//#define ACTION_STATE_PAUSE
	//#define ACTION_STATE_PLAY
	//BattleState.enum FuncUse
	//{
	//	FuncUse.AT_XSPEED_TO_ZERO,
	//	FuncUse.AT_ZSPEED_TO_ZERO,
	//	FuncUse.AT_LANDING,
	//	FuncUse.AT_UNDER_ATTACK,
	//	FuncUse.AT_TOUCH
	//}

	static LCUI_BOOL action_database_inited;
	static LCUI_Queue action_database=new LCUI_Queue();


	public static void ActionData_Destroy(IntPtr arg)
	{
		ActionData_ action;
		//action = (ActionData_)arg;
		action = (ActionData_)System.Runtime.InteropServices.Marshal.PtrToStructure(arg, typeof(ActionData_));

		Queue_Destroy(action.frame);
	}

	static ActionRec_ GameObject_FindActionRec(GameObject_ obj, int action_id)
	{
		int i;
		int n;
		ActionRec_ p_rec;
		n = Queue_GetTotal(obj.action_list);
		for(i =0; i<n; ++i)
		{
			p_rec = (ActionRec_)Queue_Get(obj.action_list, i);
			if(p_rec == null || p_rec.id != action_id)
			{
				continue;
			}
			return p_rec;
		}
		return null;
	}

	//* 检测动作中指定帧是否有新攻击 
	static LCUI_BOOL Action_IsNewAttack(ActionData_ action, int n_frame)
	{
		ActionFrameData_ p_frame;
		if(n_frame < 0)
		{
			return DefineConstantsGame_object.FALSE;
		}
		p_frame = (ActionFrameData_)Queue_Get(action.frame, n_frame);
		if (p_frame == null)
		{
			return DefineConstantsGame_object.FALSE;
		}
		return p_frame.new_attack;
	}

	static int Action_GetFrameSleepTime(ActionData_ action, int n_frame)
	{
		ActionFrameData_ frame;
		frame = (ActionFrameData_)Queue_Get(action.frame, n_frame);
		if (frame != null)
		{
			return frame.sleep_time;
		}
		return DefineConstantsGame_object.REFRESH_INTERVAL_TIME;
	}

	//* 处理与当前对象接触的对象 
	static int GameObject_ProcTouch( LCUI_Widget_ widget)
	{
		int i;
		int n;
		GameObject_ obj;
		LCUI_Widget_ tmp_obj;
		RangeBox_ my_range = new RangeBox_();
		RangeBox_ other_range = new RangeBox_();

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.at_touch==null)
		{
			return -1;
		}
		if(0 > GameObject_GetHitRange(widget,out my_range))
		{
			return -2;
		}
		n = Queue_GetTotal(obj.library);
		for(i =0; i<n; ++i)
		{
			tmp_obj = (LCUI_Widget_)Queue_Get(obj.library, i);
			if(tmp_obj == null || widget == tmp_obj)
			{
				continue;
			}
			if(0 > GameObject_GetHitRange(tmp_obj,out other_range))
			{
				continue;
			}
			if (RangeBox_IsIntersect(my_range, other_range) )
			{
				if(obj.at_touch!=null)
				{
					obj.at_touch(widget, tmp_obj);
				}
			}
		}
		return 0;
	}

	//* 处理攻击当前对象受到的攻击 
	static int GameObject_ProcAttack( LCUI_Widget_ widget)
	{
		int i;
		int n;
		LCUI_Widget_ tmp_obj;
		GameObject_ obj_data;
		RangeBox_ hit_range;//= new RangeBox_();
		RangeBox_ attack_range;// = new RangeBox_();

		// 获取该对象的受攻击范围，若获取失败，则返回NULL 
		if(0 > GameObject_GetHitRange(widget,out hit_range))
		{
			return -1;
		}
		obj_data = (GameObject_)Widget_GetPrivData(widget);
		n = Queue_GetTotal(obj_data.library);
		for(i =0; i<n; ++i)
		{
			tmp_obj = (LCUI_Widget_)Queue_Get(obj_data.library, i);
			if(tmp_obj == null || widget == tmp_obj)
			{
				continue;
			}
			// 获取对象的攻击范围，若获取失败，则继续判断下个对象 
			if(0 > GameObject_GetAttackRange(tmp_obj,out attack_range))
			{
				continue;
			}
			DEBUG_MSG("hit range, x: %d, x_width: %d, y: %d, y_width: %d, z: %d, z_width: %d\n", hit_range.x, hit_range.x_width, hit_range.y, hit_range.y_width, hit_range.z, hit_range. z_width);
			DEBUG_MSG("attack range, x: %d, x_width: %d, y: %d, y_width: %d, z: %d, z_width: %d\n", attack_range.x, attack_range.x_width, attack_range.y, attack_range.y_width, attack_range.z, attack_range. z_width);
			// 若两个范围相交 
			if (RangeBox_IsIntersect(hit_range, attack_range))
			{
				GameObject_AddVictim(tmp_obj, widget);
			}
		}
		return 0;
	}

    static void GameObjectLibrary_UpdateObjectPos( LCUI_Widget_ widget)
	{
		int n;
		int src_i =-1;
		int des_i =-1;
		int time_left = new int();
		int tmp_time_left = new int();
		LCUI_Widget_ tmp_widget;
		GameObject_ p_obj;
		GameObject_ p_tmp_obj;

		p_obj = (GameObject_)Widget_GetPrivData(widget);
		time_left = LCUI_GetTicks(p_obj.action_start_time);
		time_left -= p_obj.action_pause_ms;
		time_left = p_obj.action_total_ms - time_left;

		n = Queue_GetTotal(p_obj.library);
		while(n-->0)
		{
			tmp_widget = (LCUI_Widget_)Queue_Get(p_obj.library, n);
			if (tmp_widget == null)
			{
				continue;
			}
			if(tmp_widget == widget)
			{
				src_i = n;
				if(des_i != -1)
				{
					break;
				}
				continue;
			}
			p_tmp_obj = (GameObject_)Widget_GetPrivData(tmp_widget);
			if(p_tmp_obj.state != DefineConstantsGame_object.ACTION_STATE_PLAY)
			{
				continue;
			}
			tmp_time_left = LCUI_GetTicks(p_tmp_obj.action_start_time);
			tmp_time_left -= p_tmp_obj.action_pause_ms;
			tmp_time_left = p_tmp_obj.action_total_ms - tmp_time_left;
			if(des_i == -1 && time_left >= tmp_time_left)
			{
				des_i = n;
				if(src_i != -1)
				{
					break;
				}
			}
		}
		if(des_i == -1)
		{
			des_i = Queue_GetTotal(p_obj.library)-1;
		}
		// 若源位置和目标位置有效，则开始移动 
		if(src_i != -1)
		{
			DEBUG_MSG("src: %d, des: %d\n", src_i, des_i);
			Queue_Move(p_obj.library, des_i, src_i);
		}
	}

	static void GameObject_ExecInit( LCUI_Widget_ widget)
	{
		GameObject_ obj;

		obj = (GameObject_)Widget_NewPrivData(widget, typeof(GameObject_));

		obj.x = 0;
		obj.y = 0;
		obj.w = 0;
		obj.h = 0;
		obj.state = DefineConstantsGame_object.ACTION_STATE_PAUSE;
		obj.action_start_time = LCUI_GetTickCount();
		obj.action_pause_time = LCUI_GetTickCount();
		obj.action_total_ms = 0;
		obj.action_pause_ms = 0;
		obj.n_frame = 0;
		obj.current = null;
		obj.data_valid = DefineConstantsGame_object.FALSE;
		obj.global_center_x = 0;
		obj.global_bottom_line_y = 0;
		obj.horiz_flip = DefineConstantsGame_object.FALSE;
		obj.space_obj = null;
		//obj.shadow = Widget_New(null);
		//obj.shadow = Widget_New("shadow");
		obj.shadow_visible = DefineConstantsGame_object.TRUE;
		obj.need_fill_color = DefineConstantsGame_object.FALSE;
		obj.fill_color.red = 0;
		obj.fill_color.green = 0;
		obj.fill_color.blue = 0;

		Queue_Init(obj.action_list, typeof(ActionRec_), null);
		Queue_Init(obj.victim, typeof(LCUI_Widget_), null);
		Queue_Init(obj.attacker_info, typeof(AttackerInfo_), null);
		Queue_UsingPointer(obj.victim);

		obj.at_landing = null;
		obj.at_touch = null;
		obj.at_under_attack = null;
		obj.at_xspeed_to_zero = null;
		obj.at_zero_zspeed = null;
		obj.at_move = null;
		obj.at_zspeed = null;
		obj.target_z_speed = 0.0;
	}

	static void GameObject_ExecHide( LCUI_Widget_ widget)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		Widget_Hide(obj.shadow);
	}

	static void GameObject_ExecShow( LCUI_Widget_ widget)
	{
		GameObject_ obj;
		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.shadow_visible)
		{
			Widget_Show(obj.shadow);
		}
		else
		{
			Widget_Hide(obj.shadow);
		}
	}

	static void GameObject_ExecDestroy( LCUI_Widget_ widget)
	{
		int i;
		int n;
		GameObject_ obj;
		LCUI_Widget_ tmp_widget;

		obj = (GameObject_)Widget_GetPrivData(widget);
		//SpaceObject_Destroy( obj->space_obj );
		//Widget_Destroy(obj.shadow);
		Queue_Destroy(obj.action_list);
		Queue_Destroy(obj.victim);
		Queue_Destroy(obj.attacker_info);
		Queue_Lock(obj.library);
		n = Queue_GetTotal(obj.library);
		for(i =0; i<n; ++i)
		{
			tmp_widget = (LCUI_Widget_)Queue_Get(obj.library, i);
			if(tmp_widget == widget)
			{
				Queue_DeletePointer(obj.library, i);
				break;
			}
		}
		Queue_Unlock(obj.library);
	}

	//* 获取当前动作信息 
	static int GameObject_UpdateData( LCUI_Widget_ widget)
	{
		int i;
		int n;
		GameObject_ obj;
		LCUI_Queue frame_list;
		ActionFrameData_ frame;
		int frame_bottom_y;
		int frame_center_x;
		int box_w =0;
		int box_h =0;
		int point_x =0;
		int point_y =0;

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.current == null)
		{
			return -1;
		}
		if(obj.current.action == null)
		{
			return -1;
		}

		frame_list = obj.current.action.frame;
		n = Queue_GetTotal(obj.current.action.frame);
		for(i =0; i<n; ++i)
		{
			frame = (ActionFrameData_)Queue_Get(frame_list, i);
			if(frame == null)
			{
				continue;
			}
	//        
	//		 * frame->graph是当前帧动作的容器
	//		 * frame->graph.w 和 frame->graph.h 则是该容器的尺寸
	//		 * box_w 和 box_h 是该动作集的容器尺寸
	//		 * frame_bottom_y 是对象底线在当前帧的容器中的Y轴坐标
	//		 * frame_center_x 是对象中点在当前帧的容器中的X轴坐标
	//		 * point_y 和 point_x 与上面两个类似，但坐标是相对动作集的容器
	//		 
			frame_bottom_y = frame.graph.h + frame.offset.y;
			frame_center_x = frame.graph.w/2 + frame.offset.x;
			// 对比容器顶端到底线的距离 
			if(frame_bottom_y > point_y)
			{
				box_h = (box_h - point_y) + frame_bottom_y;
				point_y = frame_bottom_y;
			}
			// 对比底线到容器底端的距离 
			if(frame.graph.h - frame_bottom_y > box_h - point_y)
			{
				box_h = point_y + (frame.graph.h - frame_bottom_y);
			}
			// 对比容器左端到中心点的距离 
			if(frame_center_x > point_x)
			{
				box_w = (box_w - point_x) + frame_center_x;
				point_x = frame_center_x;
			}
			// 对比中心点到容器右端的距离 
			if(frame.graph.w - frame_center_x > box_w - point_x)
			{
				box_w = point_x + (frame.graph.w - frame_center_x);
			}
		}
		obj.global_center_x = point_x;
		obj.global_bottom_line_y = point_y;
		obj.w = box_w;
		obj.h = box_h;
		return 0;
	}

	static void GameObject_ExecUpdate( LCUI_Widget_ widget)
	{
		GameObject_ obj;
		LCUI_Pos_ object_pos = new LCUI_Pos_();
		LCUI_Pos_ shadow_pos = new LCUI_Pos_();

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.current == null)
		{
			obj.current = (ActionRec_)Queue_Get(obj.action_list, 0);
			// 既然没有动作动画，那就不进行更新 
			if(obj.current == null)
			{
				return;
			}
		}
		obj.x = (int)obj.space_obj.x;
		obj.y = (int)(obj.space_obj.y-obj.space_obj.z);
		// 计算部件的坐标 
		if(obj.horiz_flip)
		{
			object_pos.x = obj.x - (obj.w - obj.global_center_x);
		}
		else
		{
			object_pos.x = obj.x - obj.global_center_x;
		}
		object_pos.y = obj.y - obj.global_bottom_line_y;
		// 计算阴影的坐标 
		shadow_pos.x = (int)(obj.x - obj.shadow.size.w/2);
		shadow_pos.y = (int)(obj.space_obj.y - obj.shadow.size.h/2)-1;
		// 调整堆叠顺序 
		Widget_SetZIndex(widget, (int)obj.space_obj.y);
		Widget_SetZIndex(obj.shadow, -1000 - (int)obj.space_obj.y);
		// 移动部件的位置 
		Widget_Move(widget, object_pos);
		Widget_Move(obj.shadow, shadow_pos);
		// 如果数据还有效 
		if(obj.data_valid)
		{
			return;
		}
		// 如果在数据更新后未变化 
		if(GameObject_UpdateData(widget) != 0)
		{
			return;
		}
		if(obj.horiz_flip)
		{
			object_pos.x = obj.x - (obj.w - obj.global_center_x);
		}
		else
		{
			object_pos.x = obj.x - obj.global_center_x;
		}
		object_pos.y = obj.y - obj.global_bottom_line_y;
		shadow_pos.x = (int)(obj.x - obj.shadow.size.w/2);
		shadow_pos.y = (int)(obj.space_obj.y - obj.shadow.size.h/2)-1;

		Widget_SetZIndex(widget, (int)obj.space_obj.y);
		Widget_SetZIndex(obj.shadow, -1000 - (int)obj.space_obj.y);
		Widget_Move(widget, object_pos);
		Widget_Move(obj.shadow, shadow_pos);
		// 并调整部件的尺寸，以正常显示对象的动画 
		Widget_Resize(widget, Size(obj.w, obj.h));
		obj.data_valid = DefineConstantsGame_object.TRUE;
	}

	static void GameObject_ExecDraw( LCUI_Widget_ widget)
	{
		int n_frame;
		GameObject_ obj;
		LCUI_Pos_ pos = new LCUI_Pos_();
		ActionFrameData_ frame;
		LCUI_Queue p_queue;
		LCUI_Graph_ graph;
		LCUI_Graph_ img_buff;

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.current == null)
		{
			obj.current = (ActionRec_)Queue_Get(obj.action_list, 0);
			if(obj.current == null)
			{
				return;
			}
		}
		n_frame = obj.n_frame;
		p_queue = obj.current.action.frame;
		if(obj.n_frame == Queue_GetTotal(p_queue))
		{
			n_frame -= 1;
		}
		p_queue = obj.current.action.frame;
		// 获取当前帧动作图像 
		frame = (ActionFrameData_)Queue_Get(p_queue, n_frame);
		if(frame == null)
		{
			return;
		}
		// 计算当前帧相对于部件的坐标 
		pos.y = frame.graph.h + frame.offset.y;
		pos.y = obj.global_bottom_line_y - pos.y;
		// 获取部件自身图层的图像 
		graph = Widget_GetSelfGraph(widget);
		// 若需要将当前帧图像进行水平翻转 
		if(obj.horiz_flip)
		{
			Graph_Init(out img_buff);
			pos.x = frame.graph.w/2 - frame.offset.x;
			pos.x = obj.w - obj.global_center_x - pos.x;
			Graph_HorizFlip(frame.graph, img_buff);
			// 绘制到部件上 
			Graph_Replace(graph, img_buff, pos);
			Graph_Free(img_buff);
		}
		else
		{
			pos.x = frame.graph.w/2 + frame.offset.x;
			pos.x = obj.global_center_x - pos.x;
			Graph_Replace(graph, frame.graph, pos);
		}
		if(obj.need_fill_color)
		{
			Graph_FillColor(graph, obj.fill_color);
		}
	}

    //* 获取指定范围内的游戏对象 
    public static LCUI_Widget_ GameObject_GetObjectInRange( LCUI_Widget_ widget, RangeBox_ range, LCUI_BOOL specific_action, int action_id)
	{
		int i;
		int n;
		LCUI_Widget_ tmp_widget;
		GameObject_ obj1;
		GameObject_ obj2;
		RangeBox_ hit_range = new RangeBox_();

		obj1 = (GameObject_)Widget_GetPrivData(widget);

		if(range.x_width <= 0 || range.y_width <= 0 || range.z_width <= 0)
		{
			 return null;
		}
		// 若需要水平翻转，则翻转攻击框 
		if(obj1.horiz_flip)
		{
			range.x = (int)obj1.space_obj.x - range.x;
			range.x -= range.x_width;
		}
		else
		{
			range.x = (int)obj1.space_obj.x + range.x;
		}
		//range.x_width = range.x_width;
		range.y = (int)obj1.space_obj.y + range.y;
		//range.y_width = range.y_width;
		range.z = (int)obj1.space_obj.z + range.z;
		//range.z_width = range.z_width;

		n = Queue_GetTotal(obj1.library);
		// 遍历其它游戏对象 
		for(i =0; i<n; ++i)
		{
			tmp_widget = (LCUI_Widget_)Queue_Get(obj1.library, i);
			obj2 = (GameObject_)Widget_GetPrivData(tmp_widget);
			// 忽略其它无效对象和当前对象 
			if(obj2 == null || tmp_widget == widget)
			{
				continue;
			}
			// 判断游戏对象目前的动作是否符合要求 
			if(specific_action)
			{
				if(obj2.current == null || obj2.current.id != action_id)
				{
					 continue;
				}
			}
			// 获取该游戏对象的受攻击范围 
			if(0 > GameObject_GetHitRange(tmp_widget,out hit_range))
			{
				continue;
			}
			// 若指定的范围与受攻击范围相交，则返回该游戏对象 
			if (RangeBox_IsIntersect(range, hit_range))
			{
				return tmp_widget;
			}
		}
		return null;
	}

	//* 获取攻击范围内的游戏对象 
	public  static LCUI_Widget_ GameObject_GetObjectInAttackRange( LCUI_Widget_ widget, int attack_action_id, LCUI_BOOL specific_action, int action_id)
	{
		int i;
		int n;
		ActionRec_ p_rec = null;
		ActionFrameData_ frame;
		GameObject_ obj;
		RangeBox_ range = new RangeBox_();

		obj = (GameObject_)Widget_GetPrivData(widget);
		if(obj.current == null)
		{
			return null;
		}

		range.x = 0;
		range.x_width = 0;
		range.y = 0;
		range.y_width = 0;
		range.z = 0;
		range.z_width = 0;

		n = Queue_GetTotal(obj.action_list);
		// 在动作列表中查找 
		for(i =0; i<n; ++i)
		{
			p_rec = (ActionRec_)Queue_Get(obj.action_list, i);
			// 若该动作是指定的攻击动作 
			if(p_rec != null && p_rec.id == attack_action_id)
			{
				break;
			}
		}
		if(i >= n)
		{
			return null;
		}

		n = Queue_GetTotal(p_rec.action.frame);
		// 根据各帧动作的攻击框，计算出该动作的攻击范围 
		for(i =0; i<n; ++i)
		{
			frame = (ActionFrameData_)Queue_Get(p_rec.action.frame, i);
			if(frame == null)
			{
				continue;
			}
			if(frame.atkbox.x < range.x)
			{
				range.x_width += (range.x-frame.atkbox.x);
				range.x = frame.atkbox.x;
			}
			if(frame.atkbox.x + frame.atkbox.x_width > range.x + range.x_width)
			{
				 range.x_width = frame.atkbox.x;
				 range.x_width += frame.atkbox.x_width;
				 range.x_width -= range.x;
			}

			if(frame.atkbox.y < range.y)
			{
				range.y_width += (range.y-frame.atkbox.y);
				range.y = frame.atkbox.y;
			}
			if(frame.atkbox.y + frame.atkbox.y_width > range.y + range.y_width)
			{
				 range.y_width = frame.atkbox.y;
				 range.y_width += frame.atkbox.y_width;
				 range.y_width -= range.y;
			}

			if(frame.atkbox.z < range.z)
			{
				range.z_width += (range.z-frame.atkbox.z);
				range.z = frame.atkbox.z;
			}
			if(frame.atkbox.z + frame.atkbox.z_width > range.z + range.z_width)
			{
				 range.z_width = frame.atkbox.z;
				 range.z_width += frame.atkbox.z_width;
				 range.z_width -= range.z;
			}
		}
		return GameObject_GetObjectInRange(widget, range, specific_action, action_id);
	}

	public static LCUI_Widget_ GameObject_New(GameSpaceData_ space, ref LCUI_Queue library)
	{
		GameObject_ obj;
		LCUI_Widget_ widget;

		//widget = Widget_New("GameObject");
		widget = Widget_New("Player");
		obj = (GameObject_)Widget_GetPrivData(widget);
		obj.space_obj = GlobalMembersGame_space.SpaceObject_New(space, 0, 0, 0, 0, 0, 0);
		obj.library = library;
		Queue_AddPointer(library, widget);
		return widget;
	}

	public static void GameObject_Register()
	{
		WidgetType_Add("GameObject");
		WidgetFunc_Add("GameObject", GameObject_ExecInit, FuncType_.FUNC_TYPE_INIT);
		WidgetFunc_Add("GameObject", GameObject_ExecDraw, FuncType_.FUNC_TYPE_DRAW);
		WidgetFunc_Add("GameObject", GameObject_ExecUpdate, FuncType_.FUNC_TYPE_UPDATE);
		WidgetFunc_Add("GameObject", GameObject_ExecHide, FuncType_.FUNC_TYPE_HIDE);
		WidgetFunc_Add("GameObject", GameObject_ExecShow, FuncType_.FUNC_TYPE_SHOW);
		WidgetFunc_Add("GameObject", GameObject_ExecDestroy, FuncType_.FUNC_TYPE_DESTROY);
	}

    
}

public enum FuncType_
{
	FUNC_TYPE_SHOW,
	FUNC_TYPE_HIDE,
	FUNC_TYPE_INIT,
    FUNC_TYPE_DRAW,
	No,
	FUNC_TYPE_UPDATE,
	FUNC_TYPE_DESTROY
}
// ****************************************************************************
// * Punch And Kick -- a simple 2D Fighting Game.
// *
// * Copyright (C) 2013 by
// * Liu Chao
// *
// * This file is part of the Punch And Kick project, and may only be used,
// * modified, and distributed under the terms of the GPLv2.
// *
// * (GPLv2 is abbreviation of GNU General Public License Version 2)
// *
// * By continuing to use, modify, or distribute this file you indicate that you
// * have read the license and understand and accept it fully.
// *
// * The Punch And Kick project is distributed in the hope that it will be
// * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GPL v2 for
// * more details.
// *
// * You should have received a copy of the GPLv2 along with this file. It is
// * usually in the LICENSE.TXT file, If not, see <http://www.gnu.org/licenses/>.
// * **************************************************************************

// ****************************************************************************
// * Punch And Kick -- 一个普通的2D格斗游戏
// *
// * 版权所有 (C) 2013 归属于
// * 刘超
// *
// * 这个文件是 Punch And Kick 项目的一部分，并且只可以根据GPLv2许可协议来使用、
// * 更改和发布。
// *
// * (GPLv2 是 GNU通用公共许可证第二版 的英文缩写)
// *
// * 继续使用、修改或发布本文件，表明您已经阅读并完全理解和接受这个许可协议。
// *
// * Punch And Kick 项目是基于技术交流目的而加以散布的，但不负任何担保责任，例
// * 如：稳定性、可玩性、趣味性等的担保，甚至没有适销性或特定用途的隐含担保，详
// * 情请参照GPLv2许可协议。
// *
// * 您应已收到附随于本文件的GPLv2许可协议的副本，它通常在LICENSE.TXT文件中，如果
// * 没有，请查看：<http://www.gnu.org/licenses/>.
// * **************************************************************************

// 游戏对象模块，用于实现游戏角色的坐标控制、动作动画、攻击判定等功能。


// ****************************************************************************
// * Punch And Kick -- a simple 2D Fighting Game.
// *
// * Copyright (C) 2013 by
// * Liu Chao
// *
// * This file is part of the Punch And Kick project, and may only be used,
// * modified, and distributed under the terms of the GPLv2.
// *
// * (GPLv2 is abbreviation of GNU General Public License Version 2)
// *
// * By continuing to use, modify, or distribute this file you indicate that you
// * have read the license and understand and accept it fully.
// *
// * The Punch And Kick project is distributed in the hope that it will be
// * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GPL v2 for
// * more details.
// *
// * You should have received a copy of the GPLv2 along with this file. It is
// * usually in the LICENSE.TXT file, If not, see <http://www.gnu.org/licenses/>.
// * **************************************************************************

// ****************************************************************************
// * Punch And Kick -- 一个普通的2D格斗游戏
// *
// * 版权所有 (C) 2013 归属于
// * 刘超
// *
// * 这个文件是 Punch And Kick 项目的一部分，并且只可以根据GPLv2许可协议来使用、
// * 更改和发布。
// *
// * (GPLv2 是 GNU通用公共许可证第二版 的英文缩写)
// *
// * 继续使用、修改或发布本文件，表明您已经阅读并完全理解和接受这个许可协议。
// *
// * Punch And Kick 项目是基于技术交流目的而加以散布的，但不负任何担保责任，例
// * 如：稳定性、可玩性、趣味性等的担保，甚至没有适销性或特定用途的隐含担保，详
// * 情请参照GPLv2许可协议。
// *
// * 您应已收到附随于本文件的GPLv2许可协议的副本，它通常在LICENSE.TXT文件中，如果
// * 没有，请查看：<http://www.gnu.org/licenses/>.
// * **************************************************************************


//* 范围框 
public struct RangeBox_
{
	public int x;
	public int y;
	public int z;
	public int x_width;
	public int y_width;
	public int z_width;
    public RangeBox_(int x, int y, int z, int x_width, int y_width, int z_width)
    {
		this.x = x;
		this.y = y;
		this.z = z;
		this.x_width = x_width;
		this.y_width = y_width;
		this.z_width = z_width;
	}
 //   public RangeBox_()
 //   {
	//	this.x = 0;
	//	this.y = 0;
	//	this.z =0;
	//	this.x_width = 0;
	//	this.y_width = 0;
	//	this.z_width = 0;
	//}

	public void CopyFrom(RangeBox_ rangeBox_)
    {
		this.x = rangeBox_.x;
		this.y = rangeBox_.y;
		this.z = rangeBox_.z;
		this.x_width = rangeBox_. x_width;
		this.y_width = rangeBox_.y_width;
		this.z_width = rangeBox_.z_width;
	}
}

public class AttackerInfo_
{
	public LCUI_Widget_ attacker; //* 攻击者 
	public int attacker_action; //* 攻击者在攻击时的动作ID 
}

//
//  当前帧的中心点的Y轴平行线
//         |
//  _______|______
//  |   O        |         矩形框代表当前帧的范围
//  |  /|\       |
//  |__/_\_______|________ 底线的X轴平行线
//      |
//      |
//  对象的中点的Y轴平行线
//

//* 一帧动作的信息 
public class ActionFrameData_
{
	public LCUI_Pos_ offset = new LCUI_Pos_(); //*< 当前对象底线中点相对于该帧图像底线中点的偏移量 
	public LCUI_Graph_ graph = new LCUI_Graph_(); //*< 当前帧的图像 
	public int sleep_time; //*< 该帧显示的时长（单位：毫秒） 
	public RangeBox_ hitbox = new RangeBox_(); //*< 受攻击的范围框 
	public RangeBox_ atkbox = new RangeBox_(); //*< 攻击的范围框 
	public LCUI_BOOL new_attack = new LCUI_BOOL(); //*< 是否产生新攻击 
}

//* 动作集的信息 
public class ActionData_
{
	public LCUI_BOOL replay = new LCUI_BOOL(); //*< 标志，指示该动作是否重复播放 
	public LCUI_Queue frame = new LCUI_Queue(); //*< 用于记录该动作集的所有帧动作 
}

public enum FuncUse
{
	AT_XSPEED_TO_ZERO,
	AT_ZSPEED_TO_ZERO,
	AT_LANDING,
	AT_UNDER_ATTACK,
	AT_TOUCH
};

/** 动作记录 */
public class ActionRec_
{
	public int id;             /**< 动画的标识号 */
	public ActionData_ action;     /**< 对应的动作集 */
	public delegate void Update (LCUI_Widget_ w);    /**< 回调函数，在每帧更新时调用 */
	public delegate void Done (LCUI_Widget_ w); /**< 回调函数，在动作结束时调用 */
	//public Update update;
	//public Done done;
	public GlobalMembersGame_object.funcDelegate update;
	public GlobalMembersGame_object.funcDelegate done;
}


/** 每次数据刷新时的时间间隔(毫秒) */
//#define REFRESH_INTERVAL_TIME 20

public class GameObject_
{
	public int state;          /**< 当前状态 */
	public int x, y;           /**< 底线中点坐标 */
	public int w, h;           /**< 动作容器的尺寸 */
	public int global_bottom_line_y;   /**< 底线的Y轴坐标 */
	public int global_center_x;        /**< 中心点的X轴坐标 */

	public LCUI_BOOL data_valid=false;       /**< 当前使用的数据是否有效 */
	public LCUI_BOOL horiz_flip= false;       /**< 是否水平翻转 */

	public ActionRec_ current;     /**< 当前动作动画记录 */
	public LCUI_Queue action_list=new LCUI_Queue ();     /**< 动作列表 */

	public int n_frame;            /**< 记录当前帧动作的序号，帧序号从0开始 */
	public int action_start_time;  /**< 开始播放时的时间 */
	public int action_pause_time;  /**< 暂停时的时间 */
	public int action_total_ms;   /**< 总定时时间（单位：毫秒） */
	public int action_pause_ms;   /**< 定时器处于暂停状态的时长（单位：毫秒） */

	public SpaceObject_ space_obj;     /**< 对应的物理对象 */
	public LCUI_Widget_ shadow=new LCUI_Widget_ ();        /**< 对象的阴影 */
	public LCUI_BOOL shadow_visible=true;   /**< 阴影是否可见 */

	public LCUI_Queue victim=new LCUI_Queue() ;      /**< 当前攻击的受害者 */
	public LCUI_Queue attacker_info=new LCUI_Queue();   /**< 攻击者信息 */
	public LCUI_Queue library=new LCUI_Queue();        /**< 所属库 */

	public LCUI_BOOL need_fill_color=false;  /**< 指示是否填充颜色 */
	public LCUI_RGB_ fill_color;        /**< 需要填充的颜色 */

	public delegate void At_landing (LCUI_Widget_ w);
	public delegate void At_touch (LCUI_Widget_ w, LCUI_Widget_ wi);
	public delegate void Aat_under_attack(LCUI_Widget_ w);
	public delegate void Aat_xspeed_to_zero(LCUI_Widget_ w);
	public delegate void Aat_zero_zspeed(LCUI_Widget_ w);
	public delegate void Aat_move(LCUI_Widget_ w);
	public delegate void Aat_zspeed(LCUI_Widget_ w);

	public GlobalMembersGame_object.funcDelegate at_landing;
	public GlobalMembersGame_object.funcDelegate2 at_touch;
	public GlobalMembersGame_object.funcDelegate at_under_attack;
	public GlobalMembersGame_object.funcDelegate at_xspeed_to_zero;
	public GlobalMembersGame_object.funcDelegate at_zero_zspeed;
	public GlobalMembersGame_object.funcDelegate at_move;
	public GlobalMembersGame_object.funcDelegate at_zspeed;
	public double target_z_speed;
}